package com.wechat.page.chat.message;

import org.controlsfx.glyphfont.FontAwesome;

import com.swak.entity.YesNo;
import com.swak.fx.support.AbstractComp;
import com.swak.fx.support.AbstractPage;
import com.swak.fx.support.Display;
import com.swak.fx.support.FXMLView;
import com.swak.fx.support.ability.DragAbleAbility;
import com.swak.fx.support.ui.UIDot;
import com.swak.fx.support.ui.UIIcon;
import com.swak.fx.support.ui.UIImage;
import com.swak.fx.support.ui.UILabel;
import com.swak.fx.support.ui.UITextFlow;
import com.swak.ui.Event;
import com.swak.ui.Events;
import com.swak.utils.StringUtils;
import com.wechat.Cons;
import com.wechat.dto.ChatDTO;
import com.wechat.page.chat.popup.OpsPopup;
import com.wechat.page.comps.TextComp;
import com.wechat.page.utils.Times;

import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;

/**
 * 消息 - 缩略
 * 
 * @author 618lf
 */
@FXMLView(title = "消息", value = "MessageThumbComp.fxml", css = "MessageThumbComp.css")
public class MessageThumbComp extends AbstractComp implements TextComp {

	@FXML
	private StackPane headimgPane;
	@FXML
	private StackPane alertPane;

	@FXML
	private UILabel name;
	@FXML
	private UILabel time;
	@FXML
	private UITextFlow content;

	private UIImage image;
	private UIIcon alter;
	private UIDot unread;

	public MessageThumbComp(AbstractPage parent) {
		super(parent);
	}

	@Override
	public void initializeParts() {
		super.initializeParts();

		// 很重要 ： 固定大小
		this.time.fixedWidth();

		// 未读
		this.unread = new UIDot().Danger();

		// 图片
		this.image = new UIImage().image(Display.logo());
		this.image.setPrefSize(40, 40);
		this.headimgPane.getChildren().add(image);
		this.headimgPane.setAlignment(Pos.CENTER);
		StackPane.setAlignment(this.image, Pos.CENTER);

		// 免打扰
		this.alter = new UIIcon(FontAwesome.Glyph.BELL_O).fixedWidth();
		this.alertPane.getChildren().add(alter);
		this.alertPane.setAlignment(Pos.CENTER);

		DragAbleAbility.of(this.root, () -> this.chatProperty.get());
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
		this.root.addEventHandler(MouseEvent.MOUSE_CLICKED, this.mouseClickHandler);
	}

	@Override
	public void setupBindings() {
		super.setupBindings();
		this.activedProperty.bind(Bindings.createBooleanBinding(() -> {
			ChatDTO active = this.activeProperty().get();
			ChatDTO chat = this.chatProperty().get();
			return active != null && chat != null && active.getId().equals(chat.getId());
		}, this.activeProperty(), this.chatProperty()));
	}

	@Override
	public void setupValueChangedListeners() {
		super.setupValueChangedListeners();
		this.chatProperty().addListener((ob, o, n) -> this.onChatChange(n));
		this.refreshProperty().addListener((ob, o, n) -> this.onChatRefresh(n.longValue()));
	}

	private void onChatRefresh(Long time) {
		ChatDTO chat = this.chatProperty.get();
		if (chat != null) {
			this.onChatChange(chat);
		}
	}

	private void onChatChange(ChatDTO chat) {
		this.name.textProperty().set(chat.getNickName());
		this.time.textProperty().set(Times.formateLastTimeBrevity(chat.getLastMsgDate()));
		this.image.decorationProperty().set(chat.getUnReadCount() != null && chat.getUnReadCount() > 0 ? unread : null);
		this.alter.iconProperty()
				.set(chat.getIsAlert() != null && chat.getIsAlert() == YesNo.Yes.getType() ? FontAwesome.Glyph.BELL_O
						: FontAwesome.Glyph.BELL_SLASH_O);
		this.buildTextContent(chat);
	}

	private void buildTextContent(ChatDTO chat) {
		boolean active = this.activedProperty.get();
		boolean useDraft = !active && chat.getDraft() != null && StringUtils.isNotBlank(chat.getDraft().getBrief());
		String content = useDraft ? chat.getDraft().getBrief() : chat.getLastMsgContent(); // - 简述
		this.buildTextContent(this.content, content, useDraft);
	}

	@Override
	public void layoutParts() {
		super.layoutParts();
	}

	@Override
	public void destory() {
		super.destory();
		this.activeProperty().unbind();
		this.root.removeEventHandler(MouseEvent.MOUSE_CLICKED, this.mouseClickHandler);
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private final BooleanProperty activedProperty = new SimpleBooleanProperty(false);
	private final ObjectProperty<ChatDTO> activeProperty = new SimpleObjectProperty<>();
	private final ObjectProperty<ChatDTO> chatProperty = new SimpleObjectProperty<>();
	private final LongProperty refreshProperty = new SimpleLongProperty();

	public ObjectProperty<ChatDTO> activeProperty() {
		return activeProperty;
	}

	public ObjectProperty<ChatDTO> chatProperty() {
		return chatProperty;
	}

	public LongProperty refreshProperty() {
		return refreshProperty;
	}

	// ================================================================================
	// Event
	// ================================================================================
	EventHandler<MouseEvent> mouseClickHandler = (e) -> {
		MouseButton mb = e.getButton();
		if (mb != null && mb == MouseButton.PRIMARY) {
			this.onChatSelect(e);
		} else {
			this.onChatSetting(e);
		}
	};

	private void onChatSelect(MouseEvent event) {
		if (this.activedProperty.get()) {
			return;
		}
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("[聊天缩略] - 发送事件 ：{}", Cons.Event_Chat_Select);
		}
		Events.post(new Event(Cons.Event_Chat_Select, chatProperty.get()));
	}

	private void onChatSetting(MouseEvent event) {
		OpsPopup.newPopup().setChat(chatProperty.get()).show(this.root, event.getScreenX(), event.getScreenY());
	}
}